/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.maigao.util;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.experimental.UtilityClass;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 基于GSON的JSON解析器
 */
@UtilityClass
public class JsonUtil {

    private final Gson GSON = new Gson();

    public byte[] toBytes(Object object) {
        if (null == object) {
            return null;
        }
        return StringHelper.getBytes(toJson(object));
    }

    public String toJson(Object object) {
        if (object == null) {
            return null;
        }
        return GSON.toJson(object);
    }

    public <T> T toBean(String json, Class<T> clazz) {
        try {
            return GSON.fromJson(json, clazz);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public <T> T deepCopy(Object obj, Class<T> clazz) {
        return toBean(toJson(obj), clazz);
    }

    public <T> T[] toArr(String json, Class<T[]> classArr) {
        try {
            return GSON.fromJson(json, classArr);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public <T> List<T> toList(String json, Class<T> clazz) {
        try {
            //泛型转换
            Type type = new ParameterizedTypeImpl(clazz);
            List<T> list =  new Gson().fromJson(json, type);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public <T> T toBean(byte[] bytes, Class<T> clazz) {
        return toBean(StringHelper.getString(bytes), clazz);
    }

    public JsonObject toJsonObject(String str) {
        JsonElement jsonElement = GSON.toJsonTree(str);
        JsonObject jsonObject = jsonElement.getAsJsonObject();
        return jsonObject;
    }

    /**
     * Gson解析不支持泛型，利用ParameterizedType获取泛型参数类型
     * author: JayGengi 60167
     * email:  gengy@chinaraising.com
     * time:  2018/04/13 10:01
     */
    private class ParameterizedTypeImpl implements ParameterizedType {
        Class clazz;

        public ParameterizedTypeImpl(Class clz) {
            clazz = clz;
        }
        @Override
        public Type[] getActualTypeArguments() {
            //返回实际类型组成的数据
            return new Type[]{clazz};
        }
        @Override
        public Type getRawType() {
            //返回原生类型，即HashMap
            return List.class;
        }
        @Override
        public Type getOwnerType() {
            //返回Type对象
            return null;
        }
    }

}
